3 ...\PTVR_Researchers\Python_Scripts\Demos\Pointing\
4 reticle_in_forest_with_spheres.py
7 Show how to create a Monocular (or binocular) STANDARD PTVR reticle.
8 Note that there is no pointing interaction between the reticle and the
9 spheres or objects (i.e. no callback is called when an object is
12 The reticle is head-contingent in this demo
14 The scene is a forest* with trees at different distances to observe
15 the reticle's behaviour when its pointing cone encounters objects or
18 * This forest is a PTVR object modified from the following free asset:
19 https://assetstore.unity.com/packages/3d/environments/landscapes/low-poly-simple-nature-pack-162153
21 By default, a PTVR reticle is always rendered through any object
22 with its position calculated to be close to the object's center (See PTVR
23 Documentation -> User Manual -> Pointing at an object).
24 Thus, the similarity in position of the object and the reticle render
25 their binocular disparity similar thus avoiding double vision.
26 This default behaviour occurs when 'is_distance_constant' is set to
27 False (in ImageToContingentCursor() )
28 Another aspect of this default behaviour emerges when the reticle's pointing
29 cone is empty, i.e. when no object lies within the pointing cone. In
30 this case, the reticle is set to a distance that you can choose. This
31 distance is set to 500 m by default ('distance_if_empty_cursor_cone'=500).
33 What you can play around with:
34 You can set a constant distance for the reticle (thus changing its
36 For instance, if you want to have the reticle at 2 meters from the head,
37 gaze, eye, or hand, you have to modify the two following parameters of
38 ImageToContingentCursor :
39 is_distance_constant = True
41 If you do as defined above, then the reticle will not be visible
42 when it is behind the red sphere (the spheres are displayed at different
43 distances from the CS's origin).
45 Note : The reticle belongs to the PTVR category called "flat cursors"
46 (reminder: a scotoma also belongs to the "flat cursors" category).
64 my_contingency = ImageContingency.HEADSET
66 my_eye_w_reticle =
"both"
70 sphere_1_color = color.RGBColor(1,0,0)
71 sphere_1_pos = np.array([-1,0,1])
72 sphere_2_color = color.RGBColor(0,1,0)
73 sphere_2_pos = np.array([0,0,3])
74 sphere_3_color = color.RGBColor(0,0,1)
75 sphere_3_pos = np.array([1,0,5])
83 reticle_2D_image = RG.ReticleImageFromDrawing (
84 reticle_inner_diameter_as_ratio = 0.3,
85 reticle_line_width_as_ratio=0.1 )
89 my_reticle = ImageToContingentCursor (
90 contingency_type = my_contingency,
91 image = reticle_2D_image,
92 eye_with_contingent_cursor = my_eye_w_reticle,
93 is_distance_constant =
False,
94 constant_distance = 2 )
95 scene_name.place_contingent_cursor (my_reticle)
99 sphere_1 = Sphere ( color = sphere_1_color,
100 position_in_current_CS = sphere_1_pos)
101 sphere_2 = Sphere ( color = sphere_2_color,
102 position_in_current_CS = sphere_2_pos)
103 sphere_3 = Sphere ( color = sphere_3_color,
104 position_in_current_CS = sphere_3_pos)
105 scene_name.place (sphere_1, my_world)
106 scene_name.place (sphere_2, my_world)
107 scene_name.place (sphere_3, my_world)
111 my_world = The3DWorld ()
114 my_scene = VisualScene (skybox=
"Sunset", side_view_on_pc =
False)
117 create_reticle (my_scene)
118 create_spheres (my_scene)
120 my_forest = Forest ()
121 my_scene.place (my_forest, my_world)
123 my_sprite = Sprite (image_file =
"cat.png",
125 position_in_current_CS=np.array([3, 3, 0.0]) ,
126 rotation_in_current_CS=np.array([0.0, 90, 0.0]))
127 my_scene.place (my_sprite, my_world)
129 my_world.add_scene (my_scene)
132 if __name__ ==
"__main__":
def LaunchThe3DWorld(jsonFileCategory="Externals")
def create_spheres(scene_name)
def create_reticle(scene_name)